<!DOCTYPE html>
<html lang="zh-hans">

<head>
    
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="HandheldFriendly" content="True" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<meta name="generator" content="Hugo 0.109.0">


<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dsrkafuu/dsr-cdn-main@1/images/favicons/dsrca.ico" />



<title>深度学习框架 - OffSummer</title>


<meta name="author" content="RQY" />


<meta name="description" content="A minimal Hugo theme with nice theme color." />


<meta name="keywords" content="mindspore, DL" />


<meta property="og:title" content="深度学习框架" />
<meta name="twitter:title" content="深度学习框架" />
<meta property="og:type" content="article" />
<meta property="og:url" content="/post/03-module/" /><meta property="og:description" content="回顾
首先，我们来回顾一下前两节我们做了什么。
在第一节，我们建立了一个线性数据集，将其打包进行批量计算；通过加权求和的方式，建立了一个线性网络；使用平方误差作为损失函数；通过梯度下降的方式进行反向传播，使线性网络收敛。
在第二节，我们使用Mnist数据集，将其打包进行批量计算；使用了Softmax非线性网络；使用交叉熵作为损失函数；通过梯度下降的方式进行反向传播，使非线性网络收敛。
可以注意到，在两种方式中，我们的操作都有共同的成分，比如打开数据集、设置网络格式、选择误差函数、选择网络训练方法等。不可忽视的是，在前两节中，我们都采用手动求导的方法，进行梯度下降的操作，需要用户熟练掌握微积分。
但实际上，哪怕不是数学家或者信息学家，也能很好地使用深度学习，因为这些东西，深度学习框架都会自动帮我们处理，很多时候，我们需要做的，仅仅只是数据标注，以及超参数的调整而已，哪怕我们对模型的细节一无所知，也可以将其作为一个工具进行使用，这也是调参侠的由来。
下面，我们依照第二节，来了解一下MindSpore是如何为我们实现模型的训练的。" />
<meta name="twitter:description" content="回顾
首先，我们来回顾一下前两节我们做了什么。
在第一节，我们建立了一个线性数据集，将其打包进行批量计算；通过加权求和的方式，建立了一个线性网络；使用平方误差作为损失函数；通过梯度下降的方式进行反向传播，使线性网络收敛。
在第二节，我们使用Mnist数据集，将其打包进行批量计算；使用了Softmax非线性网络；使用交叉熵作为损失函数；通过梯度下降的方式进行反向传播，使非线性网络收敛。
可以注意到，在两种方式中，我们的操作都有共同的成分，比如打开数据集、设置网络格式、选择误差函数、选择网络训练方法等。不可忽视的是，在前两节中，我们都采用手动求导的方法，进行梯度下降的操作，需要用户熟练掌握微积分。
但实际上，哪怕不是数学家或者信息学家，也能很好地使用深度学习，因为这些东西，深度学习框架都会自动帮我们处理，很多时候，我们需要做的，仅仅只是数据标注，以及超参数的调整而已，哪怕我们对模型的细节一无所知，也可以将其作为一个工具进行使用，这也是调参侠的由来。
下面，我们依照第二节，来了解一下MindSpore是如何为我们实现模型的训练的。" /><meta property="og:image" content="/img/og.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="/img/og.png" /><meta property="article:published_time" content="2022-10-15T23:24:00+08:00" /><meta property="article:modified_time" content="2022-10-15T23:24:00+08:00" />


<style>
    @media (prefers-color-scheme: dark) {
        body[data-theme='auto'] img {
            filter: brightness(60%);
        }
    }

    body[data-theme='dark'] img {
        filter: brightness(60%);
    }
</style>




<link rel="stylesheet" href="/assets/css/fuji.min.b4a21b5d3eb1d0a51297e31230a65fc25e387843e45ec3a2d9176cd8d163c216d99b9b13a618b28f537c3b559ec8a408183b0fbfad48daddb9befa7d3ef90eed.css" integrity="sha512-tKIbXT6x0KUSl&#43;MSMKZfwl44eEPkXsOi2Rds2NFjwhbZm5sTphiyj1N8O1WeyKQIGDsPv61I2t25vvp9PvkO7Q==" />








</head>

<body
  data-theme="auto"
  data-theme-auto='true'
  >
    <script data-cfasync="false">
  
  var fujiThemeData = localStorage.getItem('fuji_data-theme');
  
  if (!fujiThemeData) {
    localStorage.setItem('fuji_data-theme', 'auto');
  } else {
    
    if (fujiThemeData !== 'auto') {
      document.body.setAttribute('data-theme', fujiThemeData === 'dark' ? 'dark' : 'light');
    }
  }
</script>

    <header>
    <div class="container-lg clearfix">
        <div class="col-12 header">
            <a class="title-main" href="/">OffSummer</a>
            
            <span class="title-sub">Summer is going, but autumn does not come yet.</span>
            
        </div>
    </div>
</header>

    <main>
        <div class="container-lg clearfix">
            
            <div class="col-12 col-md-9 float-left content">
                
<article>
    
    <h2 class="post-item post-title">
        <a href="/post/03-module/">深度学习框架</a>
    </h2>
    <div class="post-item post-meta">
        <span><i class="iconfont icon-today-sharp"></i>&nbsp;2022-10-15</span>

<span><i class="iconfont icon-file-tray-sharp"></i>&nbsp;1663 字</span>
<span><i class="iconfont icon-time-sharp"></i>&nbsp;4 分钟</span>
<span><i class="iconfont icon-pricetags-sharp"></i>&nbsp;<a href="/tags/mindspore">mindspore</a>&nbsp;<a href="/tags/dl">DL</a>&nbsp;</span>

    </div>
    
    <div class="post-content markdown-body">
        <h2 id="回顾">回顾</h2>
<p>首先，我们来回顾一下前两节我们做了什么。</p>
<p>在第一节，我们建立了一个线性数据集，将其打包进行批量计算；通过加权求和的方式，建立了一个线性网络；使用平方误差作为损失函数；通过梯度下降的方式进行反向传播，使线性网络收敛。
在第二节，我们使用Mnist数据集，将其打包进行批量计算；使用了Softmax非线性网络；使用交叉熵作为损失函数；通过梯度下降的方式进行反向传播，使非线性网络收敛。</p>
<p>可以注意到，在两种方式中，我们的操作都有共同的成分，比如打开数据集、设置网络格式、选择误差函数、选择网络训练方法等。不可忽视的是，在前两节中，我们都采用手动求导的方法，进行梯度下降的操作，需要用户熟练掌握微积分。</p>
<p>但实际上，哪怕不是数学家或者信息学家，也能很好地使用深度学习，因为这些东西，深度学习框架都会自动帮我们处理，很多时候，我们需要做的，仅仅只是数据标注，以及超参数的调整而已，哪怕我们对模型的细节一无所知，也可以将其作为一个工具进行使用，这也是调参侠的由来。</p>
<p>下面，我们依照第二节，来了解一下MindSpore是如何为我们实现模型的训练的。</p>
<h2 id="选择超参数">选择超参数</h2>
<p>在这里，我们选择批处理量为256， 学习率为0.0001，训练轮次为10轮。</p>
<pre><code class="language-python">    batch_size, lr, num_epochs = 256, 0.0001, 10
</code></pre>
<h2 id="加载数据集">加载数据集</h2>
<p>在上一节中，我们使用<code>mindvision.classification.dataset</code>中的<code>Mnist</code>可以获取Mnist的数据集。同时，它也可以直接作为MindSpore框架的数据集，使用</p>
<pre><code class="language-python">    dataset_train = Mnist(path='/shareData/mindspore-dataset/Mnist', split=&quot;train&quot;,
                          batch_size=batch_size, repeat_num=1, shuffle=True,
                          download=False, resize=28).run()
    dataset_test = Mnist(path='/shareData/mindspore-dataset/Mnist', split=&quot;test&quot;,
                         batch_size=batch_size, repeat_num=1, shuffle=True,
                         download=False, resize=28).run()
</code></pre>
<p>即可将其作为MindSpore的标准数据集输入。</p>
<p>但如果我们要使用我们自己定义的方式加载数据，则需要进行一定的处理。</p>
<p>比如说我们要使用第二节自定义的<code>load_mnist</code>函数，首先要定义一个迭代器来输出数据与标签的值</p>
<pre><code class="language-python">def synthetic_data(features, labels):
    for i in range(len(labels)):
        yield features[i]/255, labels[i]
</code></pre>
<p>要自定义数据集，我们需要引用<code>mindspore.dataset</code></p>
<pre><code class="language-python">import mindspore.dataset as ds
</code></pre>
<p>下面的代码，第二行，我们使用了上述的迭代器；第三行，利用<code>mindspore.dataset.GeneratorDataset</code>来建立MindSpore可接受的数据集；第四行与第五行，我们对其进行格式转换；第七行，我们以一个batchsize的大小将其打包。</p>
<pre><code class="language-python">def data_iter(features, labels, batch_size):
    data_gen = synthetic_data(features, labels)
    data = ds.GeneratorDataset(tuple(data_gen), ['image', 'label'], shuffle=True)
    data = data.map(operations=[TypeCast(ms.dtype.float32)])
    data = data.map(operations=[TypeCast(ms.dtype.int32)],
                    input_columns='label')
    data = data.batch(batch_size)
    return data
</code></pre>
<p>使用下面的代码，即可将我们自建的数据集转换为MindSpore的格式。</p>
<pre><code class="language-python">    features_t, labels_t = load_mnist('/shareData/mindspore-dataset/Mnist/train')
    features_v, labels_v = load_mnist('/shareData/mindspore-dataset/Mnist/test', split='t10k')

    dataset_train = data_iter(features_t, labels_t, batch_size)
    dataset_valid = data_iter(features_v, labels_v, batch_size)
</code></pre>
<h2 id="设置网络">设置网络</h2>
<p>在MindSpore中，我们的线性网络是<code>nn.Dense</code>（其实是全连接层），其计算方式为</p>
<p>$$
y = activation(WX^T+B)
$$</p>
<p>其中，activation可以是线性的，可以是非线性的，默认为线性的激活函数。</p>
<p>在官方的<a href="https://www.mindspore.cn/docs/zh-CN/r1.8/api_python/nn/mindspore.nn.Dense.html#mindspore.nn.Dense" target="_blank">文档</a>中，可以看到函数的说明：</p>
<pre><code class="language-python">mindspore.nn.Dense(in_channels, out_channels, weight_init='normal', bias_init='zeros', has_bias=True, activation=None)
</code></pre>
<p>其中，in_channels为输入的通道数，out_channels为输出的通道数，weight_init权重为初始化的方式（默认为高斯分布），bias_init为偏置的初始化方式（默认为0），has_bias为是否设置偏置，actitvation是上述提到的激活函数。</p>
<p>如果我们使用官方的数据集，可以使用下面的方式建立神经网络。</p>
<pre><code class="language-python">    net = nn.SequentialCell(
        nn.Flatten(),
        nn.Dense(28*28, 10),
    )
</code></pre>
<p>使用我们自定义的数据集，只需要下面的方式即可。</p>
<pre><code class="language-python">    net = nn.Dense(28*28, 10)
</code></pre>
<h2 id="设置损失函数">设置损失函数</h2>
<p>设置Softmax输出层的交叉熵损失函数非常简单，只需要一句话：</p>
<pre><code class="language-python">    loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')
</code></pre>
<h2 id="设置优化器">设置优化器</h2>
<p>现在，我们不需要手动求导来获得梯度了。我们可以直接使用SGD优化器，可以自动进行优化。</p>
<pre><code class="language-python">    opti = nn.SGD(net.trainable_params(), learning_rate=lr)
</code></pre>
<h2 id="回调函数">回调函数</h2>
<p>回调函数是在训练过程中会被调用的函数，在之后的章节中会详细说明（下面的函数在util.callback文件中）。</p>
<pre><code class="language-python">def get_accuracy(network, datasets):
    metric = nn.Accuracy('classification')
    for x, y in datasets:
        y_hat = network(x)
        metric.update(y_hat, y)
    return metric.eval()
</code></pre>
<pre><code class="language-python">def get_loss(network, loss_f, dataset):
    loss = 0
    for x, y in dataset:
        y_hat = network(x)
        loss += loss_f(y_hat, y)
    return loss
</code></pre>
<pre><code class="language-python">class AccuracyMonitor(ms.Callback):
    def __init__(self, valid_data):
        self.valid_data = valid_data

    def on_train_epoch_end(self, run_context):
        &quot;&quot;&quot;Called after each epoch finished.&quot;&quot;&quot;

        callback_params = run_context.original_args()

        cur_epoch_num = callback_params.cur_epoch_num
        epoch_num = callback_params.epoch_num

        network = callback_params.network

        train_data = callback_params.train_dataset

        train_accu = get_accuracy(network, train_data)
        valid_accu = get_accuracy(network, self.valid_data)

        loss = get_loss(network, callback_params.loss_fn, train_data)
        loss /= callback_params.batch_num

        print(f'epoch:[{cur_epoch_num}/{epoch_num}] Loss:{loss} Train Accuracy:{train_accu} Valid Accuracy:{valid_accu}')
</code></pre>
<h2 id="训练模型">训练模型</h2>
<p>在MindSpore提供模型训练的高阶API，使用以下的短短两行代码即可进行训练。</p>
<pre><code class="language-python">    model = ms.Model(net, loss_fn=loss, optimizer=opti, metrics={'acc'})

    model.train(num_epochs, dataset_train, callbacks=[AccuracyMonitor(dataset_valid)])
</code></pre>
<h2 id="输出结果">输出结果</h2>
<pre><code class="language-shell">epoch:[1/10] Loss:2.2774138 Train Accuracy:0.14748333333333333 Valid Accuracy:0.155
epoch:[2/10] Loss:2.252627 Train Accuracy:0.19975 Valid Accuracy:0.2083
epoch:[3/10] Loss:2.2284462 Train Accuracy:0.2749666666666667 Valid Accuracy:0.2841
epoch:[4/10] Loss:2.2046874 Train Accuracy:0.3722666666666667 Valid Accuracy:0.3815
epoch:[5/10] Loss:2.1814284 Train Accuracy:0.46326666666666666 Valid Accuracy:0.4711
epoch:[6/10] Loss:2.1586423 Train Accuracy:0.5326166666666666 Valid Accuracy:0.5395
epoch:[7/10] Loss:2.136246 Train Accuracy:0.58175 Valid Accuracy:0.588
epoch:[8/10] Loss:2.11424 Train Accuracy:0.6151666666666666 Valid Accuracy:0.6216
epoch:[9/10] Loss:2.0927134 Train Accuracy:0.6402666666666667 Valid Accuracy:0.6477
epoch:[10/10] Loss:2.071551 Train Accuracy:0.6594166666666667 Valid Accuracy:0.669
</code></pre>
    </div>
</article>




            </div>
            <aside class="col-12 col-md-3 float-left sidebar">
    
    <div class="sidebar-item sidebar-pages">
        <h3>页面</h3>
        <ul>
            
            <li>
                <a href="/">Home</a>
            </li>
            
            <li>
                <a href="/archives/">Archives</a>
            </li>
            
            <li>
                <a href="/about/">About</a>
            </li>
            
            <li>
                <a href="/search/">Search</a>
            </li>
            
            <li>
                <a href="/index.xml">RSS</a>
            </li>
            
        </ul>
    </div>
    
    <div class="sidebar-item sidebar-links">
        <h3>链接</h3>
        <ul>
            
            <li>
                <a href="https://github.com/ruaqy" target="_blank"><span>GitHub</span></a>
            </li>
            
            <li>
                <a href="https://gitee.com/ruqy" target="_blank"><span>Gitee</span></a>
            </li>
            
            <li>
                <a href="https://space.bilibili.com/13382902" target="_blank"><span>Bilibili</span></a>
            </li>
            
        </ul>
    </div>
    
    <div class="sidebar-item sidebar-tags">
        <h3>标签</h3>
        <div>
            
            <span>
                <a href="/tags/dl/">DL</a>
            </span>
            
            <span>
                <a href="/tags/make-up/">Make Up</a>
            </span>
            
            <span>
                <a href="/tags/matlab/">MATLAB</a>
            </span>
            
            <span>
                <a href="/tags/mindspore/">mindspore</a>
            </span>
            
            <span>
                <a href="/tags/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/">机器学习</a>
            </span>
            
        </div>
    </div>
    <div class="sidebar-item sidebar-toc">
        <h3>目录</h3><nav id="TableOfContents">
  <ul>
    <li><a href="#回顾">回顾</a></li>
    <li><a href="#选择超参数">选择超参数</a></li>
    <li><a href="#加载数据集">加载数据集</a></li>
    <li><a href="#设置网络">设置网络</a></li>
    <li><a href="#设置损失函数">设置损失函数</a></li>
    <li><a href="#设置优化器">设置优化器</a></li>
    <li><a href="#回调函数">回调函数</a></li>
    <li><a href="#训练模型">训练模型</a></li>
    <li><a href="#输出结果">输出结果</a></li>
  </ul>
</nav></div>
</aside>

        </div>
        <div class="btn">
    <div class="btn-menu" id="btn-menu">
        <i class="iconfont icon-grid-sharp"></i>
    </div>
    <div class="btn-toggle-mode">
        <i class="iconfont icon-contrast-sharp"></i>
    </div>
    <div class="btn-scroll-top">
        <i class="iconfont icon-chevron-up-circle-sharp"></i>
    </div>
</div>
<aside class="sidebar-mobile" style="display: none;">
  <div class="sidebar-wrapper">
    
    <div class="sidebar-item sidebar-pages">
        <h3>页面</h3>
        <ul>
            
            <li>
                <a href="/">Home</a>
            </li>
            
            <li>
                <a href="/archives/">Archives</a>
            </li>
            
            <li>
                <a href="/about/">About</a>
            </li>
            
            <li>
                <a href="/search/">Search</a>
            </li>
            
            <li>
                <a href="/index.xml">RSS</a>
            </li>
            
        </ul>
    </div>
    
    <div class="sidebar-item sidebar-links">
        <h3>链接</h3>
        <ul>
            
            <li>
                <a href="https://github.com/ruaqy" target="_blank"><span>GitHub</span></a>
            </li>
            
            <li>
                <a href="https://gitee.com/ruqy" target="_blank"><span>Gitee</span></a>
            </li>
            
            <li>
                <a href="https://space.bilibili.com/13382902" target="_blank"><span>Bilibili</span></a>
            </li>
            
        </ul>
    </div>
    
    <div class="sidebar-item sidebar-tags">
        <h3>标签</h3>
        <div>
            
            <span>
                <a href="/tags/dl/">DL</a>
            </span>
            
            <span>
                <a href="/tags/make-up/">Make Up</a>
            </span>
            
            <span>
                <a href="/tags/matlab/">MATLAB</a>
            </span>
            
            <span>
                <a href="/tags/mindspore/">mindspore</a>
            </span>
            
            <span>
                <a href="/tags/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/">机器学习</a>
            </span>
            
        </div>
    </div>
    
    
    
    <div class="sidebar-item sidebar-toc">
        <h3>目录</h3>
        <nav id="TableOfContents">
  <ul>
    <li><a href="#回顾">回顾</a></li>
    <li><a href="#选择超参数">选择超参数</a></li>
    <li><a href="#加载数据集">加载数据集</a></li>
    <li><a href="#设置网络">设置网络</a></li>
    <li><a href="#设置损失函数">设置损失函数</a></li>
    <li><a href="#设置优化器">设置优化器</a></li>
    <li><a href="#回调函数">回调函数</a></li>
    <li><a href="#训练模型">训练模型</a></li>
    <li><a href="#输出结果">输出结果</a></li>
  </ul>
</nav>
    </div>
    
    
  </div>
</aside>
    </main>

    <footer>
    <div class="container-lg clearfix">
        <div class="col-12 footer">
            
            <p>
                除特殊注明部分，本站内容采用 <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 进行许可。
            </p>
            
            <span>&copy; 2023-2023
                <a href="/">RQY</a>
                 | <a href="https://github.com/dsrkafuu/hugo-theme-fuji">Source code</a> 
                | 基于 <a href="https://github.com/dsrkafuu/hugo-theme-fuji/"
                   target="_blank">Fuji-v2</a> &amp; <a href="https://gohugo.io/"
                                                    target="_blank">Hugo</a> 构建
            </span>
        </div>
    </div>
</footer>

    
<script defer src="https://cdn.jsdelivr.net/npm/medium-zoom@1.0.6/dist/medium-zoom.min.js" integrity="sha512-N9IJRoc3LaP3NDoiGkcPa4gG94kapGpaA5Zq9/Dr04uf5TbLFU5q0o8AbRhLKUUlp8QFS2u7S+Yti0U7QtuZvQ==" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/lazysizes@5.3.2/lazysizes.min.js" integrity="sha512-q583ppKrCRc7N5O0n2nzUiJ+suUv7Et1JGels4bXOaMFQcamPk9HjdUknZuuFjBNs7tsMuadge5k9RzdmO+1GQ==" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/components/prism-core.min.js" integrity="sha512-LCKPTo0gtJ74zCNMbWw04ltmujpzSR4oW+fgN+Y1YclhM5ZrHCZQAJE4quEodcI/G122sRhSGU2BsSRUZ2Gu3w==" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/plugins/autoloader/prism-autoloader.min.js" integrity="sha512-GP4x8UWxWyh4BMbyJGOGneiTbkrWEF5izsVJByzVLodP8CuJH/n936+yQDMJJrOPUHLgyPbLiGw2rXmdvGdXHA==" crossorigin="anonymous"></script>



<script defer src="/assets/js/fuji.min.645f1123be695831f419ab54c1bcba327325895c740014006e57070d4f3e5d6b553e929c4b46f40ea707249e9c7f7c2a446d32a39ce7319f80a34525586a8e0f.js" integrity="sha512-ZF8RI75pWDH0GatUwby6MnMliVx0ABQAblcHDU8&#43;XWtVPpKcS0b0DqcHJJ6cf3wqRG0yo5znMZ&#43;Ao0UlWGqODw=="></script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.css" integrity="sha512-07YhC3P4/vS5HdgGuNAAeIxb5ee//efgRNo5AGdMtqFBUPYOdQG/sDK0Nl5qNq94kdEk/Pvu8pmN4GYUeucUkw==" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.js" integrity="sha512-aMDiFsrEV3KzAn9EHwyBRS7y1APjZWt/Z/73ukLN2Ca2KcGGzlOQFQSnfOdnEcehpwMaQ8edlDB/0cMX2GsHbg==" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/contrib/auto-render.min.js" integrity="sha512-ZA/RPrAo88DlwRnnoNVqKINnQNcWERzRK03PDaA4GIJiVZvGFIWQbdWCsUebMZfkWohnfngsDjXzU6PokO4jGw==" crossorigin="anonymous"></script>
<script>
  renderMathInElement(document.querySelector('div.content'), {
    delimiters: [
      { left: '$$', right: '$$', display: true },
      { left: '\\[', right: '\\]', display: true },
      { left: '$', right: '$', display: false },
      { left: '\\(', right: '\\)', display: false },
    ],
  });
</script>




</body>

</html>
